package dk.au.cs.peterbn.xml;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;

import java.io.InputStream;

/**
 * Resolver for the RelaxNG schemas in a jar file
 */
class SchemaResolver implements LSResourceResolver {

    private static final Logger logger = LoggerFactory.getLogger(SchemaResolver.class);
    public static final String XHTML = "xhtml/";
    public static final String SCHEMAS = "schemas/";
    public static final String MODULES = "modules/";


    @Override
    public LSInput resolveResource(String type,
                                   String namespaceURI,
                                   String publicId,
                                   String systemId,
                                   String baseURI) {
        DOMImplementationRegistry registry;
        String path;
        if (systemId.endsWith("designpattern.rnc")
                || systemId.endsWith("external.rnc")
                ) {
            path = SCHEMAS + systemId;
        } else if (systemId.startsWith(XHTML)) {
            path = SCHEMAS + systemId;
        } else if (systemId.startsWith(MODULES)) {
            path = SCHEMAS + XHTML + systemId;
        } else {
            path = SCHEMAS + XHTML + MODULES + systemId;
        }

        if (path != null) {
            try {

                registry = DOMImplementationRegistry.newInstance();
                DOMImplementationLS domImplementationLS = (DOMImplementationLS) registry
                        .getDOMImplementation("LS 3.0");

                LSInput ret = domImplementationLS.createLSInput();
                ret.setSystemId(systemId);
                InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
                ret.setByteStream(inputStream);
                return ret;

            } catch (ClassCastException e) {
                logger.error(e.getMessage());
            } catch (ClassNotFoundException e) {
                logger.error(e.getMessage());
            } catch (InstantiationException e) {
                logger.error(e.getMessage());
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage());
            }
        }

        logger.error("No stream found for system id [{}]", systemId);
        return null;
    }

}
